# Advanced State Management

<EpicVideo url="https://www.epicreact.dev/workshops/advanced-react-apis/intro-to-advanced-state-management" />

React's `useState` hook can get you a really long way with React state
management. That said, sometimes you want to separate the state logic from the
components that make the state changes. In addition, if you have multiple
elements of state that typically change together, then having an object that
contains those elements of state can be quite helpful.

This is where `useReducer` comes in really handy.

This exercise will take you pretty deep into `useReducer`. Typically, you'll use
`useReducer` with an object of state, but we're going to start by managing a
single number (a `count`). We're doing this to ease you into `useReducer` and
help you learn the difference between the convention and the actual API.

Here's an example of using `useReducer` to manage the value of a name in an
input.

```tsx
function nameReducer(previousName: string, newName: string) {
	return newName
}

const initialNameValue = 'Joe'

function NameInput() {
	const [name, setName] = useReducer(nameReducer, initialNameValue)
	const handleChange = (event) => setName(event.currentTarget.value)
	return (
		<div>
			<label>
				Name: <input defaultValue={name} onChange={handleChange} />
			</label>
			<div>You typed: {name}</div>
		</div>
	)
}
```

One important thing to note here is that the reducer (called `nameReducer`
above) is called with two arguments:

1. the current state
2. whatever it is that the dispatch function (called `setName` above) is called
   with. This is often called an "action."

📜 Here are two really helpful blog posts comparing `useState` and `useReducer`:

- [Should I useState or useReducer?](https://kentcdodds.com/blog/should-i-usestate-or-usereducer)
- [How to implement useState with useReducer](https://kentcdodds.com/blog/how-to-implement-usestate-with-usereducer)
